import requests
import datetime
import pandas as pd
from httpsig.requests_auth import HTTPSignatureAuth


class JumpServer:
    def __init__(self):
        """
        JumpServer api登陆信息，认证方式参考JumpServer官网api文档
        """
        self.KEY_ID = ''
        self.SECRET = ''
        self.signature_headers = ['(request-target)', 'accept', 'date', 'host']
        self.GMT_FORMAT = '%a, %d %b %Y %H:%M:%S GMT'
        self.headers = {
            'Accept': 'application/json',
            'Date': datetime.datetime.now().strftime(self.GMT_FORMAT)
        }
        self.auth = HTTPSignatureAuth(key_id=self.KEY_ID, secret=self.SECRET,
                                      algorithm='hmac-sha256',
                                      headers=self.signature_headers)
        self.host = ''
        self.platform = 'Linux'

    def __get_node_id(self, full_path):
        """
        获取资产节点id
        :param full_path: 节点路径
        :return: node_id
        """
        response = requests.get(url='http://{}/api/v1/assets/nodes/'.format(self.host),
                                auth=self.auth, headers=self.headers)
        node_list_json = response.json()
        node_list = pd.DataFrame.from_records(node_list_json, columns=["id", "name", "full_value", "key"])
        node_list["full_value"] = node_list["full_value"].str.replace(" ", "")
        node_id = node_list["full_value"] == full_path
        return node_list[node_id]["id"].str.cat() if node_id.any() else None

    # 创建新资产，参数依次为内网ip，节点名称，机器名称
    def create_new_asset(self, ip, full_path, hostname):
        """
        创建资产。
        :param ip: 待创建资产内网ip
        :param full_path: 待创建资产所属部门路径
        :param hostname: 待创建资产hostname
        :return: 请求状态码
        """
        node_id = self.__get_node_id(full_path)
        data = {
            'hostname': hostname,
            'ip': ip,
            'protocols': 'ssh/52113',
            'nodes': node_id,
            'platform': self.platform,
            'admin_user': '',
            'is_active': True
        }
        response = requests.post("http://{}/api/v1/assets/assets/".format(self.host),
                                 auth=self.auth, headers=self.headers, data=data)
        if response.status_code == 201:
            print("%s add into %s SUCCESSED" % (ip, full_path))
        elif response.status_code == 400:
            print("%s 在%s中存在" % (ip, full_path))
        else:
            print("%s add into %s FAILED" % (ip, full_path))
        return response.status_code

    def get_assets(self):
        """
        获取跳板机机器信息。
        :return: {ip: id}
        """
        asset_dict = {}
        response = requests.get('http://{}/api/v1/assets/assets/'.format(self.host),
                                auth=self.auth, headers=self.headers)
        asset_list = response.json()
        for asset in asset_list:
            asset_dict[asset['ip']] = asset['id']
        return asset_dict

    # 删除资产，参数为资产id
    def delete_asset(self, id):
        """
        删除资产
        :param id: 跳板机资产id
        :return: 请求状态码
        """
        response = requests.delete(f"""http://{self.host}/api/v1/assets/assets/{id}/""",
                                   auth=self.auth,
                                   headers=self.headers
                                   )
        print("DELETED {} is SUCCESSFUL!!".format(id)) if response.status_code == 204 else print(response.status_code)
        return response.status_code
